package com.lznAdmin.system.service.impl;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.system.HostInfo;
import cn.hutool.system.OsInfo;
import cn.hutool.system.RuntimeInfo;
import cn.hutool.system.SystemUtil;
import cn.hutool.system.oshi.OshiUtil;
import com.lznAdmin.system.service.SysMonitoringService;
import org.springframework.stereotype.Service;
import oshi.SystemInfo;
import oshi.hardware.GlobalMemory;
import oshi.software.os.OSFileStore;

import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @program: lznAdmin-pro
 * @description:
 * @author: lzn
 * @create: 2021-10-27 11:16
 **/
@Service
public class SysMonitoringServiceImpl implements SysMonitoringService {

    final double byteNum = Math.pow(1024, 3);

    @Override
    public Dict getMemoryInfo() {
        GlobalMemory memory = OshiUtil.getMemory();
        BigDecimal memoryTotal = NumberUtil.round(memory.getTotal() / byteNum, 2);
        BigDecimal memoryAvailable = NumberUtil.round(memory.getAvailable() / byteNum, 2);
        BigDecimal memoryUsed = NumberUtil.sub(memoryTotal, memoryAvailable);
        BigDecimal memoryUsageRate = NumberUtil.round(NumberUtil.mul(NumberUtil.div(memoryUsed, memoryTotal), 100), 2);
        return Dict.create().set("memoryTotal", memoryTotal)
                .set("memoryUsed", memoryUsed)
                .set("memoryAvailable", memoryAvailable)
                .set("memoryUsageRate", memoryUsageRate);
    }

    @Override
    public Dict getJVMInfo() {

        // JVM内存信息
        RuntimeInfo runtimeInfo = SystemUtil.getRuntimeInfo();
        BigDecimal JvmMaxMemory = NumberUtil.round(runtimeInfo.getMaxMemory() / byteNum, 2);
        BigDecimal JvmUsedMemory = NumberUtil.sub(NumberUtil.round(runtimeInfo.getTotalMemory() / byteNum, 2), NumberUtil.round(runtimeInfo.getFreeMemory() / byteNum, 2));
        BigDecimal JvmUsableMemory = NumberUtil.round(runtimeInfo.getUsableMemory() / byteNum, 2);
        BigDecimal JvmUsageRate = NumberUtil.round(NumberUtil.mul(NumberUtil.div(JvmUsedMemory, JvmMaxMemory), 100), 2);
        return Dict.create().set("JvmMaxMemory", JvmMaxMemory)
                .set("JvmUsedMemory", JvmUsedMemory)
                .set("JvmUsableMemory", JvmUsableMemory)
                .set("JvmUsageRate", JvmUsageRate);
    }

    @Override
    public Dict getJavaInfo() {
        Date startDate = new Date(ManagementFactory.getRuntimeMXBean().getStartTime());
        String jvmStartDateTime = DateUtil.format(startDate, "yyyy-MM-dd HH:mm:ss");
        String jvmRunTime = DateUtil.formatBetween(startDate, DateUtil.date(), BetweenFormatter.Level.MINUTE);
        return Dict.create().set("startTime", jvmStartDateTime).set("runTime", jvmRunTime)
                .set("javaVersion", SystemUtil.getJavaInfo().getVersion()).set("javaHomeDir", System.getProperties().getProperty("java.home"));
    }

    @Override
    public Dict getServerInfo() {
        OsInfo osInfo = SystemUtil.getOsInfo();
        HostInfo hostInfo = SystemUtil.getHostInfo();
        return Dict.create().set("osName", osInfo.getName()).set("osArch", osInfo.getArch())
                .set("hostName", hostInfo.getName()).set("hostAddress", hostInfo.getAddress());
    }

    @Override
    public List<OSFileStore> getDiskInfo() {
        SystemInfo si = new SystemInfo();
        return si.getOperatingSystem().getFileSystem().getFileStores();
    }
}
